package com.renke.jutils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 常用工具类
 * @author Renke
 * @create 2020-06-04 13:51:13
 * @docs 
 * @version
 */
public class U {
	
	public static final  Logger logger = LoggerFactory.getLogger(Util.class);
	/***************************************************************************
	 * 类常用公共方法集合
	 ***************************************************************************/
//	public static Object result(Object obj) {
//		
//	}
	/***************************************************************************
	 * 集合类常用公共方法集合
	 ***************************************************************************/
	public static boolean isValid(Object obj) {
		return (obj != null && !obj.toString().isEmpty()) ? true: false;
	}
	public static boolean isInvalid(Object obj) {
		return !isValid(obj);
	}
	public static <T> boolean isInvalidFields(T obj) {
		if(!isValid(obj)) {
			return true;
		}
		Class<?> clazz = obj.getClass();

		for(Method method:Arrays.asList(clazz.getDeclaredMethods())) {
			if(method.getName().indexOf("get")==0 && method.getParameters().length==0) {
				
				try {
					if((method.invoke(obj, null)!=null) && method.getName().indexOf("getSerialVersionUID")!=0) {
						return false;
					}
				} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		}
		return true;
	}
	public static boolean isInvalid(Object obj1,Object obj2) {
		return !isValid(obj1) || !isValid(obj2);
	}
	public static boolean isInvalid(Object obj1,Object obj2,Object obj3) {
		return isInvalid(obj1,obj2) || !isValid(obj3);
	}
	public static boolean isInvalid(Object obj1,Object obj2,Object obj3,Object obj4) {
		return isInvalid(obj1,obj2,obj3) || !isValid(obj4);
	}
	public static boolean isInvalid(Object obj1,Object obj2,Object obj3,Object obj4,Object obj5) {
		return isInvalid(obj1,obj2) || isInvalid(obj3,obj4) || !isValid(obj5);
	}
	public static boolean isNull(Object obj) {
		return obj == null;
	}
	public static boolean isNotNull(Object obj) {
		return obj != null;
	}
	public static <E> boolean isValid(List<E> list) {
		return (list != null && !list.isEmpty()) ? true: false;
	}
	public static <E> boolean isInvalid(List<E> list) {
		return !isValid(list);
	}
	public static <K,V> boolean isValid(Map<K,V> map) {
		return (map != null && !map.isEmpty()) ? true: false;
	}
	public static <K,V> boolean isInvalid(Map<K,V> map) {
		return !isValid(map);
	}
	
	public static <K,V> Map<K,V> sortMapByKey(Map<K,V> map){
		List<Map.Entry<K,V>> list = new ArrayList<Map.Entry<K,V>>(map.entrySet());
		// 通过比较器实现比较排序
		Collections.sort(list, new Comparator<Map.Entry<K,V>>() {
		    @Override
		    public int compare(Map.Entry<K,V> map1, Map.Entry<K,V> map2) {
		    	
		        return ((String) map1.getKey()).compareTo((String) map2.getKey());
		    }

		});
		return map;
	}
	public static <T> void addList(List<T> list, T obj) {
		if(U.isValid(obj)) {
			list.add(obj);
		}
	}
	/***************************************************************************
	 * 字符串常用公共方法集合
	 ***************************************************************************/
	/**
	 * 判断字符串变量是否有为空
	 * @param val
	 * @return true 或 false
	 */
	public static boolean isValid(String value) {
		return (value!=null && !value.isEmpty()) ? true : false;
	}
	public static boolean isInvalid(String value) {
		return !isValid(value);
	}
	public static String getNullStr(String value) {
		return (value!=null && !value.isEmpty()) ? value : "";
	}
	public static String getNullStr(Integer value) {
		return (value!=null) ? value.toString() : "";
	}
	/**
	 * 判断目标字符串中是否存在关键字
	 * @param text 字符串
	 * @param key 关键字
	 * @return
	 */
	public static Boolean isExists(String text, String key) {
		return (isValid(text) && text.indexOf(key)>-1) ? true : false;
	}
	public static Boolean isExists(String text, List<String> key) {
		for(String s: key) {
			if(isExists(text,s)) {
				return true;
			}
		}
		return false;
	}
	public static Boolean isExists(String text, String... key) {
		for(int i=0; i<key.length;++i) {
			if(isExists(text, key[i])) {
				return true;
			}
		}
		return false;
	}
	public static Boolean equalsAtLeastOne(String text, String... key) {
		for(int i=0; i<key.length;++i) {
			if(text.equals(key[i])) {
				return true;
			}
		}
		return false;
	}
	/**
	 * 判断字符串是否是数字
	 * @param value
	 * @return
	 */
	public static Boolean isNumber(String value) {
		if(U.isInvalid(value)) {return false;}
		try {
			Double.parseDouble(value);
			return true;
		} catch (Exception e) {
			return false;
		}
	}
	public static Boolean isInteger(String value) {
		if(U.isInvalid(value)) {return false;}
		try {
			Integer.parseInt(value);
			return true;
		} catch (Exception e) {
			return false;
		}
	}
	public static Boolean isLong(String value) {
		if(U.isInvalid(value)) {return false;}
		try {
			
			Long.parseLong(value);
			return true;
		} catch (Exception e) {
			return false;
		}
	}
	/**
	 * 返回所给的多个字符串中非空的字符串
	 * 		若有多个非空，则返回按从左至右的顺序中的首个字符串
	 * @param message
	 * @param exceptionMsg
	 * @return
	 */
	public static String getValidOne(String s1, String s2) {
		if(isValid(s1)) {
			return s1;
		} 
		return s2;
	}
	public static Integer getValidOne(Integer i1, Integer i2) {
		if(isValid(i1)) {
			return i1;
		} 
		return i2;
	}
	public static Object getValidOne(Object obj1, String obj2) {
		if(isValid(obj1)) {
			return obj1;
		} 
		return obj2;
	}
	public static String getValidOne(String s1, String s2, String s3) {
		return getValidOne(getValidOne(s1, s2), s3);
	}
	/**
	 * 返回合并prefix+text+suffix拼接的字符串
	 * 若text是空串或null，则返回空串
	 * @param prefix
	 * @param text
	 * @param suffix
	 * @return String prefix+text+suffix or ""
	 */
	public static String getValidString(String prefix,String text,String suffix) {
		return (isValid(text)?prefix+text+suffix:"");
	}
	/**
	 * 返回合并prefix+text拼接的字符串
	 * 若text是空串或null，则返回空串
	 * @param prefix
	 * @param text
	 * @return String prefix+text or ""
	 */
	public static String getValidString(String prefix,String text) {
		return (isValid(text)?prefix+text:"");
	}
	/**
	 * 返回合并text+suffix拼接的字符串
	 * 若text是空串或null，则返回空串
	 * @param text
	 * @param suffix
	 * @return String text+suffix or ""
	 */
	public static String getValidStringSuffix(String text,String suffix) {
		return (isValid(text)?text+suffix:"");
	}
	/**
	 * 返回text本身（非空字符串）或空串
	 * 若text是空串或null，则返回空串
	 * @param text
	 * @return String text or ""
	 */
	public static String string(String text) {
		return (isValid(text)?text:"");
	}
	/**
	 * 返回字符串省略后剩余的内容，结尾带上省略号"..."
	 * @param string
	 * @param length
	 * @return
	 */
	public static String stringEtc(String string, int length) {
		if(U.isValid(string) && length <= string.length())
			return string.substring(0,length)+"...";
		return string;
	}
	
	/**
	 * 将下划线命名法转换为驼峰命名法
	 * @param snakeCase
	 * @return
	 */
	public static String snakeCaseToCamelCase(String snakeCase) {
		String camelCase="";
		int index = snakeCase.indexOf('_');
//		while(index>-1) {
//			camelCase += snakeCase.substring(0, index);
//			snakeCase = snakeCase.substring(index+1);
//			snakeCase.
//			index = snakeCase.indexOf('_');
//		}
		if(index>-1) {
			snakeCase = snakeCase.toLowerCase();
			for(String str: snakeCase.split("_")) {
				String prefix = str.substring(0,1);
				camelCase += prefix.toUpperCase()+str.substring(1);
			}
			String prefix = camelCase.substring(0,1);
			camelCase = prefix.toLowerCase()+camelCase.substring(1);
		}else {
			camelCase = snakeCase;
		}
		
		return camelCase;
	}
	
	
	/***************************************************************************
	 * SQL常用公共方法集合
	 ***************************************************************************/
	public static String getLike(String value) {
		return "%"+value+"%";
	}
	/**
	 * 按行打印
	 * @param obj
	 */
	public static void println(Object obj) {
		System.out.println(obj.toString());
		
	}
	/**
	 * 获取固定长度的字符串字串，从首位开始
	 * 如 subString("123456",3)返回"123"
	 */
	public static String subString(String s,int length) {

		if(s.length()<length) {
			length = s.length();
		}
		return s.substring(0,length);
	}
	public static void syncSQL(int insertSelective) throws Exception {
		if(insertSelective<1) {
			throw new SQLException("保存失败");
		}
	}
	/***************************************************************************
	 * 日期类常用公共方法集合
	 ***************************************************************************/
	public final static long MILLISENCOND = 1;
	public final static long SENCOND = 1000 * MILLISENCOND;
	public final static long MINUTE = 60 * SENCOND;
	public final static long HOUR = 60 * MINUTE;
	public final static long DAY = 24 * HOUR;
	public final static long WEEK = 7 * DAY;
	/**
	 * MONTH
	 *	0 - 28 * DAY,
	 *	1 - 29 * DAY,
	 *	2 - 30 * DAY,
	 *	3 - 31 * DAY
	 */
	public final static long MONTH[] = {
			28 * DAY,
			29 * DAY,
			30 * DAY,
			31 * DAY
	};
	/**
	 * YEAR
	 *	0 - 365 * DAY,
	 *	1 - 366 * DAY,
	 */
	public final static long YEAR[] = {
			365 * DAY,
			366 * DAY,
	};
	/**
	 * 获取当前时间
	 * @return 
	 */
	public static Date getNowDateTime() {
		return new Date();
	}
	
	public static Date getDate(String date, String dateFormat) {
		DateFormat format = new SimpleDateFormat(dateFormat);
		try {
			return format.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
			return new Date();
		}
	}
	public static Date getDate(String date) {
		DateFormat format = new SimpleDateFormat();
		try {
			return format.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
			return new Date();
		}
	}
	//计算日期相差天数
	public static int getDays(Date beg,Date end) {
		long lbeg = beg.getTime();
		long lend = end.getTime();
		int days = (int) ((lend-lbeg)/(DAY));
		return days;
	}
	//获取添加天数日期
	public static Date addDays(Date date,Integer days) {
		long lDays = (long)days * DAY;
		long lDate = date.getTime() + lDays;
		return new Date(lDate);
	}
	//获取添加小时日期时间
	public static Date addHour(Date date,Integer hours) {
		long lDays = (long)hours * HOUR;
		long lDate = date.getTime() + lDays;
		return new Date(lDate);
	}
	public static Date getMinmumDate() {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(0);
		return cal.getTime();
	}

	public static long getDays(long millSeconds) {
		long days = millSeconds / DAY;
		return days;
	}

	//出生日期换算成岁数
	public String getAgeByBirthday(Date birthDay){
		String age = "";
		Calendar birth = Calendar.getInstance();
		birth.setTime(birthDay);
		Calendar now = Calendar.getInstance();
		now.setTime(new Date());
		Long days = (Long)(new Date().getTime() - birthDay.getTime())/(DAY);
		if((DateUtil.isLeapYear(now.get(Calendar.YEAR)) && days <= 366) || days <= 365) {
			if (now.get(Calendar.MONTH) == birth.get(Calendar.MONTH) && now.get(Calendar.YEAR) == birth.get(Calendar.YEAR)){
				age=now.get(Calendar.DATE)- birth.get(Calendar.DATE)+"天";
            } else {
            	//计算月
            	double cha = (int)(now.get(Calendar.MONTH) - birth.get(Calendar.MONTH));
                if (cha < 0) {
                	cha += 12;
                }
                age = cha+"月";
            }
		} else {
            return now.get(Calendar.YEAR) - birth.get(Calendar.YEAR)+"岁";
        }
		return age;

	}
	/**
	 * 设置日期
	 * @param oldDateTime
	 * @param date
	 * @return
	 */
	public static Date setDate(Date oldDateTime, String date) {
		String[] dateTime = DateUtil.DateToString(oldDateTime, 2).split(" ");
		String time = dateTime[1];
		Date newDateTime = DateUtil.StringToDate(date.trim()+" "+time.trim(), 2);
		return newDateTime;
	}
	/**
	 * 设置时间
	 * @param oldDateTime
	 * @param date
	 * @return
	 */
	public static Date setTime(Date oldDateTime, String time) {
		String[] dateTime = DateUtil.DateToString(oldDateTime, 2).split(" ");
		String date = dateTime[0];
		Date newDateTime = DateUtil.StringToDate(date.trim()+" "+time.trim(), 2);
		return newDateTime;
	}
	
	/***************************************************************************
	 * 异常处理常用公共方法集合
	 ***************************************************************************/
	/**
	 * 异常栈打印
	 * @param e
	 */
	public static void errorPrint(Exception e) {
		logger.info(e.getMessage());
		for(StackTraceElement element: e.getStackTrace()) {
			logger.error(element.toString());
		}
		
		
	}
	/********************************************************************************
	 * Number 数字计算相关公共方法
	 ********************************************************************/
	/**
	 * 大数字的乘法
	 * @param b1
	 * @param b2
	 * @return
	 */
	public static BigDecimal mutiply(BigDecimal b1,Short b2) {
		return b1.multiply(new BigDecimal(b2));
	}
	public static BigDecimal mutiply(BigDecimal b1,Integer b2) {
		return b1.multiply(new BigDecimal(b2));
	}
	public static BigDecimal mutiply(BigDecimal b1,Long b2) {
		return b1.multiply(new BigDecimal(b2));
	}
	public static BigDecimal mutiply(BigDecimal b1,Float b2) {
		return b1.multiply(new BigDecimal(b2));
	}
	public static BigDecimal mutiply(BigDecimal b1,Double b2) {
		return b1.multiply(new BigDecimal(b2));
	}
	public static BigDecimal add(BigDecimal b1, String s1) {
		return b1.add(new BigDecimal(s1));
	}
	
	public static BigDecimal getBigDecimal(String val) {
		if(U.isInvalid(val))return null;
		return new BigDecimal(val);
		
	}
	public static BigDecimal roundFloorInt(BigDecimal val) {
		if(val.setScale(0,BigDecimal.ROUND_FLOOR).compareTo(val)==0) {
			return val.setScale(0,BigDecimal.ROUND_FLOOR);
		}
		return val;
	}
	public static BigDecimal roundFloor(BigDecimal val,int scale) {
		try {
			return val.setScale(scale,BigDecimal.ROUND_FLOOR);
		} catch (Exception e) {
			// TODO: handle exception
			return val;
		}
	}
	/**
	 * 数值型 交换算法
	 * @param x
	 * @param y
	 */
	public static <N extends Number> void swap(N x, N y) {
		try {
			Class<?> clazz = x.getClass();
			Field value = clazz.getDeclaredField("value");
			Constructor<?> constructor = clazz.getConstructor(value.getType());
			value.setAccessible(true);
			Object temp = constructor.newInstance(x);
			value.set(x, y);
			value.set(y, constructor.newInstance(temp));//防止
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 判断 value与targe是否相等，是返回true，否返回false
	 * 其中targe作为判断对象必须赋值
	 * @param value
	 * @param target
	 * @return
	 */
	public static boolean equalsInt(Integer value, int target) {
		try {
			if(value.equals(target)) {return true;}
		}catch (Exception e) {
			return false;
		}
		return false;
	}
	public static List<String> split(String string, String regex) {
		if(U.isInvalid(string)) {
			return new ArrayList<>();
		}
		return new ArrayList<>(Arrays.asList(string.split(regex)));
	}
	
	
	/***************************************************************
	 * Thread 线程常用方法
	 */
	public static void sleep(int m) {
		try {
			Thread.sleep(m);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void sleep(int m,int n) {
		try {
			Thread.sleep(m,n);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
}
